package loader

import (
	"encoding/json"
	"iot-base/common/cache"
	"strconv"
)

//modbus参数
type Param struct {
	//ID    string
	Begin uint16 `json:"begin"`
	Count uint16 `json:"count"` //数量
	Func  string `json:"func"`  //使用解析属性函数名称
	//大端,小端配置,大端为true,默认为大端
	Endian bool `json:"bigend"`
	//是否需要进行高低字节转换
	Swap bool `json:"swap"`
	//需要进行乘法操作的值 此数值不能为零
	Number *float32 `json:"number"`
	//乘法进行完成后进行加法运算
	Additive *float32 `json:"additive"`
	//数组偏移
	IndexOffset *int `json:"indexOffset"`
	//数组大小
	Size *int `json:"arrayCount"`
	//数组起始发送地址
	BeginPos *int `json:"beginPos"`
}

//扫描命令
type Scan struct {
	Code  string `json:"code"`  //使用功能码
	Begin uint16 `json:"begin"` //开始位置
	Count uint16 `json:"count"` //读取数量
}

//从modbus协议翻译为属性
type PropertyExplain struct {
	PID         string `json:"pid"`          //属性id
	SubID       string `json:"sid"`          //属性子id
	Index       int    `json:"index"`        //数组结构使用
	ModbusParam Param  `json:"modbus_param"` //modbus使用
	//Function    string //使用解析函数
}

//控制参数
type ServiceParam struct {
	ParamID string `json:"param_id"` //服务参数ID
	//Code    string //功能码
	//Address uint16 //控制地址
	//Count   uint16 //控制的总地址
	Param Param `json:"param"` //属性参
	//Value    []byte
	//Function string
}

//控制命令
type ServiceCmd struct {
	ScanCmd      string          `json:"scan_cmd"` //服务名称
	InputParams  *[]ServiceParam `json:"input_params"`
	Scan         *Scan           `json:"scan"`
	OutputParams []OutParam      `json:"output_params"`
}

type OutParam struct {
	ID       string `json:"param_id"`
	OutParam Param  `json:"param"`
}

type PropertyScan struct {
	ScanCmd          Scan              `json:"scand_cmd"`
	PropertyExplains []PropertyExplain `json:"property_explains"`
}

type Protocol struct {
	ProtocolType string //协议类型，tcp/rtu/dtu/ascii
	SlaveId      byte   //从站地址
	//ConnectParam  string `json:"connect_param"`
	Params        map[string]interface{}
	PropertyScans []PropertyScan `json:"property_scans"`
	ServiceCmds   []ServiceCmd   `json:"service_cmds"`
}

//GetProtocolParam
func GetProtocolParam(id string) (*Protocol, error) {
	pro, pThing, err := cache.GetProtocol(id)
	if err == nil {
		if pro == "" {
			return nil, nil
		}
		var protocol Protocol
		err := json.Unmarshal([]byte(pro), &protocol)
		if err == nil {
			protocol.ProtocolType = pThing.GetThingParam("modbusType", "dtu")
			slave, err := strconv.ParseUint(pThing.GetThingParam("slaveID", "1"), 10, 8)
			protocol.SlaveId = byte(slave)
			if len(pThing.Params) > 0 {
				protocol.Params = make(map[string]interface{})
				for v, k := range pThing.Params {
					protocol.Params[v] = k
				}
			}
			//protocol.Params = pThing.Params
			return &protocol, err
		}
		return nil, err
	}
	return nil, err
}
